package com.webull.information.center.carwler.common.util.jsoup;

import java.net.Proxy;
import java.util.Optional;

import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.jsoup.Connection;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.webull.information.center.carwler.common.util.CarwlerNetWorksUtil;

/**
 * 网页解析
 *
 * @author shimingjun
 * @version 1.0
 * @date 2016年8月18日 上午9:50:18
 * @since JDK 1.8
 */
@Component
public class HttpJsoupClient {
    protected final Logger logger = LogManager.getLogger(getClass());
    private @Autowired
    CarwlerNetWorksUtil networksIPUtil;

    public Document parseDocumentFromUrl(String url) {
			return parseDocumentFromUrl(url, JsoupModel.PC0, false);
    }
	public Document parseDocumentFromUrl(String url, JsoupModel model) {
			return parseDocumentFromUrl(url, model, false);
	}
    public Document parseDocumentFromUrl(String url, boolean proxy) {
			return parseDocumentFromUrl(url, JsoupModel.PC0, networksIPUtil.isProxyOpen(proxy));
    }

	public Document parseDocumentFromUrl(String url, JsoupModel model, boolean proxy) {
		try {
			return parseDocument(url, model, networksIPUtil.isProxyOpen(proxy));
		} catch (Exception e) {
			logger.error(e);
		}
		return null;
	}

	private Document parseDocument(String url2, JsoupModel model, Boolean proxy) throws Exception {
        long startTime = System.currentTimeMillis();
        Document doc = null;
        CarwlerNetWorksUtil.ProxyService proxySer = null;
        try {

			Connection connection = model.adderModel(Jsoup.connect(url2));
			// connection.userAgent(
			// "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko)
			// Chrome/50.0.2661.102 Safari/537.36")
			// // .header("x-client-data",
			// // "CIq2yQEIpbbJAQjEtskBCP2VygEIwpjKAQjwnMoB")
			// .header("x-client-data", RandomStringUtils.randomAlphanumeric(40));


            proxySer = networksIPUtil.smartProxyModel(proxy);
            Optional.ofNullable(proxySer)
                    .ifPresent(p -> connection.proxy(new Proxy(Proxy.Type.SOCKS, p.genSocketAddress())));

            doc = connection.timeout(12000).get();

        } catch (Exception e) {
            logger.warn("parseDocumentFromUrl costTime:{},proxy:{},proxySer:{},error:" + url2,
                    (System.currentTimeMillis() - startTime), proxy, proxySer, e);
        }
        return doc;
    }

    /**
     * 简化url,去除掉协议部分，例如http(s)//(www)后 MD5摘要
     *
     * @param url
     * @return
     * @since 0.1.0
     */

    public static UrlPart getUrlPart(String url) {
        String regex = "(?i)^http[s]?[:]?(//)?(www.)?";
        String finishUrl = StringUtils.replacePattern(url, regex, "");
        // HOST部分小写2
        String host = StringUtils.lowerCase(StringUtils.substringBefore(finishUrl, "/"));
        String path = StringUtils.substringAfter(finishUrl, "/");
        path = StringUtils.isNotBlank(path) ? "/" + path : "";
        finishUrl = host + path;
        return new UrlPart(host, path, finishUrl);
    }

    public static String finishingMd5Url(String url) {
        String finishUrl = getUrlPart(url).getFinishUrl();
        if (StringUtils.isNotBlank(finishUrl)) {
            return DigestUtils.sha1Hex(finishUrl);
        }
        return null;
    }


    public static class UrlPart {
        private String host;
        private String path;
        private String finishUrl;

        public UrlPart(String host, String path, String finishUrl) {
            super();
            this.host = host;
            this.path = path;
            this.finishUrl = finishUrl;
        }

        public String getHost() {
            return host;
        }

        public void setHost(String host) {
            this.host = host;
        }

        public String getPath() {
            return path;
        }

        public void setPath(String path) {
            this.path = path;
        }

        public String getFinishUrl() {
            return finishUrl;
        }

        public void setFinishUrl(String finishUrl) {
            this.finishUrl = finishUrl;
        }

    }

}
